fixed gamma correction issues
authorØyvind Kolås <ok@src.gnome.org>
Thu, 18 Aug 2005 18:36:44 +0000 (18:36 +0000)
committerØyvind Kolås <ok@src.gnome.org>
Thu, 18 Aug 2005 18:36:44 +0000 (18:36 +0000)
ChangeLog
babl/base/model-gray.c
babl/base/model-grayscale.c
babl/base/model-rgb.c
babl/base/model-ycbcr.c
babl/base/rgb-constants.h
babl/base/util.h
tests/rgb_to_lab_to_rgb.c
tests/rgb_to_ycbcr.c

index ea069a9186f843980fa67c166e82304ae62d2e5c..fccf39ac2bf8780072b938b724ac5829dea6bc96 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2005-08-18  Øyvind Kolås  <pippin@gimp.org>
+
+       * babl/base/util.h: added new and hopefully correct gamma correction
+       and uncorrection functions.
+       * babl/base/model-grayscale.c: (components),
+       (rgb_to_grayscale_2_2), (grayscale_2_2_to_rgb): register
+       "luminance-gamma2.2" component, and use new gamma functions.
+       * babl/base/model-rgb.c: (g3_gamma_2_2), (g3_inv_gamma_2_2): use new
+       gamma functions.
+       * babl/base/model-ycbcr.c: (components), (models), (rgb_to_ycbcr),
+       (ycbcr_to_rgb): use gamma corrected luminance, and correct gamma. (pixel_formats):
+       uncomment until a new data type exist with headroom/footrom in 8bit
+       for proper rescaling of 0..255 to 16..235 for luma and  +/-112 range
+       with offset of 128 for chroma (16 thorugh 240 inclusive).
+       * babl/base/rgb-constants.h: more digits as well as some #if 0' dead
+       code for reference.
+       * tests/rgb_to_lab_to_rgb.c: add more colors to the test buffer.
+       * tests/rgb_to_ycbcr.c: set TOLERANCE to a more meaningful value,
+       updated the ycbcr version of 50% gray.
+
 2005-08-17  Øyvind Kolås  <pippin@gimp.org>
 
        * babl/babl-internal.h: (type_name##_id) babl_log upon failed
index 20d31eb8943b101ef329788884dacde11b5caa71..821a75e78cc4c734bcbe06feb27246cb5aae55e1 100644 (file)
@@ -41,6 +41,12 @@ components (void)
    "id",    BABL_LUMINANCE,
    "luma",
    NULL);
+
+  babl_component_new (
+   "luminance-gamma2.2", 
+   "id",    BABL_LUMINANCE_GAMMA_2_2,
+   "luma",
+   NULL);
 }
 
 static void
@@ -137,7 +143,7 @@ rgb_to_grayscale_2_2 (int    src_bands,
       luminance  = red   * RGB_LUMINANCE_RED +
                    green * RGB_LUMINANCE_GREEN +
                    blue  * RGB_LUMINANCE_BLUE;
-      *(double*)dst[0] = pow (luminance, 2.2);
+      *(double*)dst[0] = linear_to_gamma_2_2 (luminance);
 
       if (dst_bands==2)
         *(double*)dst[1] = alpha;
@@ -163,7 +169,7 @@ grayscale_2_2_to_rgb (int    src_bands,
       double red, green, blue;
       double alpha;
 
-      luminance = pow (*(double *)src[0], (1.0F/2.2F));
+      luminance = gamma_2_2_to_linear (*(double *)src[0]);
       red       = luminance;
       green     = luminance;
       blue      = luminance;
index 20d31eb8943b101ef329788884dacde11b5caa71..821a75e78cc4c734bcbe06feb27246cb5aae55e1 100644 (file)
@@ -41,6 +41,12 @@ components (void)
    "id",    BABL_LUMINANCE,
    "luma",
    NULL);
+
+  babl_component_new (
+   "luminance-gamma2.2", 
+   "id",    BABL_LUMINANCE_GAMMA_2_2,
+   "luma",
+   NULL);
 }
 
 static void
@@ -137,7 +143,7 @@ rgb_to_grayscale_2_2 (int    src_bands,
       luminance  = red   * RGB_LUMINANCE_RED +
                    green * RGB_LUMINANCE_GREEN +
                    blue  * RGB_LUMINANCE_BLUE;
-      *(double*)dst[0] = pow (luminance, 2.2);
+      *(double*)dst[0] = linear_to_gamma_2_2 (luminance);
 
       if (dst_bands==2)
         *(double*)dst[1] = alpha;
@@ -163,7 +169,7 @@ grayscale_2_2_to_rgb (int    src_bands,
       double red, green, blue;
       double alpha;
 
-      luminance = pow (*(double *)src[0], (1.0F/2.2F));
+      luminance = gamma_2_2_to_linear (*(double *)src[0]);
       red       = luminance;
       green     = luminance;
       blue      = luminance;
index 8d5f28daf49a98410622569952e97ed0f437c4c9..15b63e6a013959942324097fa45312768ca59d4c 100644 (file)
@@ -206,7 +206,7 @@ g3_gamma_2_2 (int    src_bands,
     {
       int band;
       for (band=0;band<3;band++)
-        *(double*)dst[band] = pow (*(double*) src[band], 2.2);
+        *(double*)dst[band] = linear_to_gamma_2_2 (*(double*) src[band]);
       for (;band<dst_bands;band++)
         *(double*)dst[band] = *(double*) src[band];
 
@@ -231,7 +231,7 @@ g3_inv_gamma_2_2 (int    src_bands,
       int band;
       for (band=0;band<3;band++)
         {
-          *(double*)dst[band] = pow (*(double*) src[band], (1.0F/2.2F));
+          *(double*)dst[band] = gamma_2_2_to_linear (*(double*) src[band]);
         }
       for (;band<dst_bands;band++)
         {
index 59a8518cd53cbfc026ac2d026adeef0ad5661588..3c2feba85cde059e52163676e13df155c2bcce4a 100644 (file)
@@ -43,13 +43,13 @@ components (void)
 {
   babl_component_new (
    "cb",
-   "id",    BABL_CB,
+   "id", BABL_CB,
    "chroma",
    NULL);
 
   babl_component_new (
    "cr",
-   "id",    BABL_CR,
+   "id", BABL_CR,
    "chroma",
    NULL);
 }
@@ -60,7 +60,7 @@ models (void)
   babl_model_new (
     "ycbcr",
     "id", BABL_YCBCR,
-    babl_component_id (BABL_LUMINANCE),
+    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
     babl_component_id (BABL_CB),
     babl_component_id (BABL_CR),
     NULL);
@@ -68,7 +68,7 @@ models (void)
   babl_model_new (
     "ycbcra",
     "id", BABL_YCBCRA,
-    babl_component_id (BABL_LUMINANCE),
+    babl_component_id (BABL_LUMINANCE_GAMMA_2_2),
     babl_component_id (BABL_CB),
     babl_component_id (BABL_CR),
     babl_component_id (BABL_ALPHA),
@@ -94,13 +94,10 @@ rgb_to_ycbcr (int    src_bands,
 
       double luminance, cb, cr;
 
-      /* values taken from Charles Poynton's color FAQ 
-       * http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC28
-       *
-       * this is YPbPr not YCbCr to be exact, it uses the full range, maybe
-       * both should be included with babl under their proper name
-       * 
-       */
+      red   = linear_to_gamma_2_2 (red);
+      green = linear_to_gamma_2_2 (green);
+      blue  = linear_to_gamma_2_2 (blue);
+      
       luminance =  0.299    * red  +0.587    * green  +0.114    * blue;
       cb        = -0.168736 * red  -0.331264 * green  +0.5      * blue;
       cr        =  0.5      * red  -0.418688 * green  -0.081312 * blue;
@@ -135,17 +132,14 @@ ycbcr_to_rgb (int    src_bands,
 
       double red, green, blue;
 
-      /* values taken from Charles Poynton's color FAQ 
-       * http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC28
-       * 
-       * this is YPbPr not YCbCr to be exact, it uses the full range, maybe
-       * both should be included with babl under their proper name
-       * 
-       */
       red   = 1.0 * luminance  + 0.0      * cb  + 1.40200    * cr;
       green = 1.0 * luminance  - 0.344136 * cb  - 0.71414136 * cr;
       blue  = 1.0 * luminance  + 1.772    * cb  + 0.0        * cr;
 
+      red   = gamma_2_2_to_linear (red);
+      green = gamma_2_2_to_linear (green);
+      blue  = gamma_2_2_to_linear (blue);
+
       *(double*)dst[0] = red;
       *(double*)dst[1] = green;
       *(double*)dst[2] = blue;
@@ -207,6 +201,7 @@ conversions (void)
 static void
 pixel_formats (void)
 {
+#if 0
   babl_pixel_format_new (
     "yuv420",
     "id",          BABL_YUV420,
@@ -218,7 +213,6 @@ pixel_formats (void)
     babl_sampling  (2, 2), babl_component_id (BABL_CR),
     NULL);
   
-#if 0
   babl_pixel_format_new (
     "yuv411",
     "id",          BABL_YUV411,
index b91d2fc85da52a98370b3c3ca8c5e01d06c0dead..76c61bd4cd309737a732a22d849155c34234d68d 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-#define RGB_LUMINANCE_RED   (0.2126)
-#define RGB_LUMINANCE_GREEN (0.7152)
-#define RGB_LUMINANCE_BLUE  (0.0722)
+//#define CONTEMPORARY_MONITOR
+
+#ifdef CONTEMPORARY_MONITOR
+  /* source: http://www.poynton.com/ColorFAQ.html */
+  #define RGB_LUMINANCE_RED    (0.212671)
+  #define RGB_LUMINANCE_GREEN  (0.715160)
+  #define RGB_LUMINANCE_BLUE   (0.072169)
+#else
+  /* this is not correct, but the constants are kept around */
+  #define RGB_LUMA_RED         (0.299)
+  #define RGB_LUMA_GREEN       (0.587)
+  #define RGB_LUMA_BLUE        (0.114)
+  #define RGB_LUMINANCE_RED    RGB_LUMA_RED   
+  #define RGB_LUMINANCE_GREEN  RGB_LUMA_GREEN 
+  #define RGB_LUMINANCE_BLUE   RGB_LUMA_BLUE
+#endif
index a9d8753a1118929e8621407da954a398b68c7ff5..038bc404242b946d8b6571bfe384262e75ac33dc 100644 (file)
@@ -21,6 +21,7 @@
 #define _UTIL_H
 
 #include <assert.h>
+#include <math.h>
 
 #define BABL_PLANAR_SANITY  \
   {                         \
   }
 
 #endif
+
+#define BABL_USE_SRGB_GAMMA
+
+#ifdef BABL_USE_SRGB_GAMMA
+
+static inline double
+linear_to_gamma_2_2 (double value)
+{
+  if (value > 0.0030402477F)
+    return 1.055F * pow (value, (1.0F/2.4F)) - 0.055F;
+  return 12.92F * value;
+}
+
+static inline double
+gamma_2_2_to_linear (double value)
+{
+  if (value > 0.03928F)
+    return pow ((value + 0.055F) / 1.055F, 2.4F);
+  return value / 12.92F;
+}
+
+#else
+  #define linear_to_gamma_2_2(value) (pow((value), (1.0F/2.2F)))
+  #define gamma_2_2_to_linear(value) (pow((value), 2.2F))
+#endif
index cf4c87079f8cd8315b8a0f593556cecfcebb0319..eec4f2722a1f4e31f8378372f1b746e8d4e47ca5 100644 (file)
 #include "babl.h"
 #include "babl-internal.h"
 
-#define PIXELS 6
+#define PIXELS 32
 #define TOLERANCE 0.001 
 
 float source_buf [PIXELS*3]=
-  {0.0, 0.0, 0.0,
-   0.5, 0.5, 0.5,
+  {1.0, 1.0, 1.0,
    1.0, 1.0, 1.0,
-   1.0, 0.0, 0.0,
+   0.0, 1.0, 1.0,
    0.0, 1.0, 0.0,
-   0.0, 0.0, 1.0};
+   1.0, 0.0, 1.0,
+   1.0, 0.0, 0.0,
+   1.0, 0.0, 1.0,
+   0.0, 0.0, 0.0,
+  
+   0.75, 0.75, 0.75,
+   0.75, 0.75, 0.75,
+   0.0,  0.75, 0.75,
+   0.0,  0.75, 0.0,
+   0.75, 0.0,  0.75,
+   0.75, 0.0,  0.0,
+   0.75, 0.0,  0.75,
+   0.0,  0.0,  0.0,
+   
+   0.5, 0.5, 0.5,
+   0.5, 0.5, 0.5,
+   0.0, 0.5, 0.5,
+   0.0, 0.5, 0.0,
+   0.5, 0.0, 0.5,
+   0.5, 0.0, 0.0,
+   0.5, 0.0, 0.5,
+   0.0, 0.0, 0.0,
+
+   0.25, 0.25, 0.25,
+   0.25, 0.25, 0.25,
+   0.0,  0.25, 0.25,
+   0.0,  0.25, 0.0,
+   0.25, 0.0,  0.25,
+   0.25, 0.0,  0.0,
+   0.25, 0.0,  0.25,
+   0.0,  0.0,  0.0
+  };
 
 float temp_buf        [PIXELS*3];
 float destination_buf [PIXELS*3];
index 8462067e6e9c85863dd110b92d122a5884be4a22..1208698d09a37020dc0220b377837f34113506db 100644 (file)
@@ -23,7 +23,7 @@
 #include "babl-internal.h"
 
 #define PIXELS 6
-#define TOLERANCE 0.00000000000001
+#define TOLERANCE 0.000001
 
 float source_buf [PIXELS*3]=
   {0.0, 0.0, 0.0,
@@ -34,12 +34,12 @@ float source_buf [PIXELS*3]=
    0.0, 0.0, 1.0};
 
 float reference_buf [PIXELS*3]=
-  {0.0,    0.0,       0.0,
-   0.5,    0.0,       0.0,
-   1.0,    0.0,       0.0,
-   0.299, -0.168736,  0.5,
-   0.587, -0.331264, -0.418688,
-   0.114,  0.5,      -0.081312};
+  {0.0,       0.0,       0.0,
+   0.735357,  0.0,       0.0,
+   1.0,       0.0,       0.0,
+   0.299,    -0.168736,  0.5,
+   0.587,    -0.331264, -0.418688,
+   0.114,     0.5,      -0.081312};
 
 
 float destination_buf [PIXELS*3];